package edu.scut.ga.reconf;

import java.util.Collection;

import javolution.context.ConcurrentContext;

import org.jenetics.CharacterChromosome;
import org.jenetics.CharacterGene;
import org.jenetics.CompositeAlterer;
import org.jenetics.FitnessFunction;
import org.jenetics.GeneticAlgorithm;
import org.jenetics.Genotype;
import org.jenetics.Optimize;
import org.jenetics.PartiallyMatchedCrossover;
import org.jenetics.SwapMutator;
import org.jenetics.util.CharSet;
import org.jenetics.util.Factory;
import com.interpss.core.aclf.AclfNetwork;
import edu.scut.ga.general.GAUtils;

// TODO：继续设计适应度函数，按照编码得到网络拓扑结构，进行到编写判断网络结构的代码
// 1. 如何拷贝或克隆网络对象？
// 2. 为何有时不移去支路？
public class ReconfMinLossGA {
	
	private LossFunction data;
	private String networkName;

	// 构造函数，初始化所需字段
	public ReconfMinLossGA(String networkName) {
		this.networkName = networkName;
//		DistributionNetworkImporter dni = new DistributionNetworkImporter(networkName);
		this.data = new LossFunction(this.networkName);
//		this.data.setNewNetwork(dni.getNetwork());
//		this.data.setColInterconnectionID(dni.getColInterconnectionID());
	}
	
	public AclfNetwork getNetwork() {
		return data.getNewNetwork();
	}

	public Collection<String> getColInterconnectionID() {
		return data.getColInterconnectionID();
	}
	
	public LossFunction getData() {
		return data;
	}

	// 执行遗传算法，得到最终的优化结果
	public void implementGA() {
		// 2. 执行遗传算法，获得最优结果
		ConcurrentContext.setConcurrency(0);
		final CharSet chars = new CharSet("012");	// 因需三状态编码，只能采用字符型染色体编码
		final FitnessFunction<CharacterGene, Double> ff = new LossFunction(this.networkName);
		Genotype<CharacterGene> initGTF = Genotype.valueOf(new CharacterChromosome(new CharSet("0"), this.data.getColInterconnectionID().size()));
		Double initLoss = ff.evaluate(initGTF);
		final Factory<Genotype<CharacterGene>> gtf = Genotype.valueOf(new CharacterChromosome(chars, this.data.getColInterconnectionID().size()));
		final GeneticAlgorithm<CharacterGene, Double> ga = GeneticAlgorithm.valueOf(gtf, ff, Optimize.MINIMUM);
//		ga.setPopulationSize(200);
		ga.setPopulationSize(20);
        ga.setAlterer(new CompositeAlterer<CharacterGene>(new SwapMutator<CharacterGene>(0.2), 
        		new PartiallyMatchedCrossover<CharacterGene>(0.3)));
//		final int generations = 200;
		final int generations = 20;
		GAUtils.printConfig("Capacitor optimization wit DSY", ga, generations, 
				((CompositeAlterer<?>)ga.getAlterer()).getAlterers().toArray());
		GAUtils.execute(ga, generations, 50);
		System.out.println("Initial loss: " + initLoss + "kVA");		
	}

}